using System;
using System.IO;
using System.Windows.Forms;

namespace Sparklings.LevelEditor
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            newLevelMessageBox = new NewLevelMessageBox();
            CreateFileDialogs();
            buttonLoad.Click += LoadLevel;
            buttonSave.Click += SaveLevel;
            buttonNewLevel.Click += NewLevel;
            buttonHelp.Click += (x, y) => ShowHelp();
            buttonTestLevel.Click += SwitchTestMode;
            InitLevelSettingsTab();
            InitTileChoiceTab();
            TestModeChanged += delegate
            {
                if (InPlayMode)
                {
                    tabControlMain.Hide();
                    buttonLoad.Enabled = false;
                    buttonSave.Enabled = false;
                    buttonNewLevel.Enabled = false;
                }
                else
                {
                    tabControlMain.Show();
                    buttonLoad.Enabled = true;
                    buttonSave.Enabled = true;
                    buttonNewLevel.Enabled = true;
                }
            };
        }

        public TileListEntry GetCurrentTileType()
        {
            return listBoxTileChoice.SelectedItem as TileListEntry;
        }
        private void CreateTileChoiceList()
        {
            listBoxTileChoice.BeginUpdate();
            listBoxTileChoice.Items.Add(new TileListEntry("Plateform", TileListEntry.OnPlacedPlateform));
            listBoxTileChoice.Items.Add(new TileListEntry("Air", TileListEntry.OnPlacedEmpty));
            listBoxTileChoice.Items.Add(new TileListEntry("Spawner", TileListEntry.OnPlacedSpawner, new TileListNeededData { Color = true, Count = true }));
            listBoxTileChoice.Items.Add(new TileListEntry("Exit point", TileListEntry.OnPlacedExit, new TileListNeededData { Color = true }));
            listBoxTileChoice.Items.Add(new TileListEntry("Spot plateform", TileListEntry.OnPlacedSpotPlateform, new TileListNeededData { Color = true, Color2 = true }));
            listBoxTileChoice.Items.Add(new TileListEntry("Blue plateform", TileListEntry.OnPlacedBluePlateform));
            listBoxTileChoice.Items.Add(new TileListEntry("Killing tile", TileListEntry.OnPlacedKillingTile));
            listBoxTileChoice.Items.Add(new TileListEntry("Star", TileListEntry.OnPlacedStarTile));
            listBoxTileChoice.Items.Add(new TileListEntry("Filter", TileListEntry.OnPlacedFilterTile, new TileListNeededData { Color = true }));
            listBoxTileChoice.ItemHeight = 200;
            listBoxTileChoice.EndUpdate();
            listBoxTileChoice.SelectedIndexChanged += delegate(object o, EventArgs a)
            {
                comboBoxColorPicker.Visible = GetCurrentTileType().NeededData.Color;
                comboBoxColorPickerOther.Visible = GetCurrentTileType().NeededData.Color2;
                numericUpDownSparklingsPerTile.Visible = GetCurrentTileType().NeededData.Count;
                groupBoxTileState.Visible = GetCurrentTileType().NeededData.State;
            };
            listBoxTileChoice.SelectedIndex = 0;
        }
        private void CreateColorPicker()
        {
            foreach (string s in Enum.GetNames(typeof(Sparklings.RayTracing.RayColor)))
            {
                comboBoxColorPicker.Items.Add(s);
            }
            comboBoxColorPicker.SelectedIndex = 0;
            foreach (string s in Enum.GetNames(typeof(Sparklings.RayTracing.RayColor)))
            {
                comboBoxColorPickerOther.Items.Add(s);
            }
            comboBoxColorPickerOther.SelectedIndex = 0;
        }
        private void CreateFileDialogs()
        {
            openFileDialog = new OpenFileDialog();
            saveFileDialog = new SaveFileDialog();
            openFileDialog.RestoreDirectory = true;
            saveFileDialog.RestoreDirectory = true;
            string levelsDirPath = Application.StartupPath + @"\..\..\..\SparklingsContent\Levels";
            openFileDialog.InitialDirectory = levelsDirPath;
            saveFileDialog.InitialDirectory = levelsDirPath;
            Console.WriteLine(levelsDirPath);
            saveFileDialog.DefaultExt = "lvl";
            openFileDialog.Filter = "Level files (*.lvl)|*.lvl|All files (*.*)|*.*";
            saveFileDialog.Filter = "Level files (*.lvl)|*.lvl|All files (*.*)|*.*";
            openFileDialog.Multiselect = false;
            saveFileDialog.OverwritePrompt = false;
            openFileDialog.Title = "Level to load";
            saveFileDialog.Title = "Level to save";
        }
        private void InitLevelSettingsTab()
        {
            numericUpDownSparklingsToSave.ValueChanged += delegate
            {
                SparklingsGameControl.level.SparklingsNeeded = (int)numericUpDownSparklingsToSave.Value;
            };
            textBoxLevelName.TextChanged += delegate
            {
                SparklingsGameControl.level.Name = textBoxLevelName.Text;
            };
            textBoxHelpText.TextChanged += delegate
            {
                SparklingsGameControl.level.HelpText = textBoxHelpText.Text;
            };
        }
        private void InitTileChoiceTab()
        {
            CreateColorPicker();
            CreateTileChoiceList();
        }
        private void NewLevel(Object sender, EventArgs e)
        {
            newLevelMessageBox.ShowDialog(this);
        }
        private void LoadLevel(Object sender, EventArgs e)
        {
            try
            {
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    using (var stream = openFileDialog.OpenFile())
                    {
                        using (var streamReader = new StreamReader(openFileDialog.OpenFile()))
                        {
                            SparklingsGameControl.LoadLevel(streamReader.ReadToEnd());
                            textBoxLevelName.Text = SparklingsGameControl.level.Name;
                            textBoxHelpText.Text = SparklingsGameControl.level.HelpText;
                            numericUpDownSparklingsToSave.Value = SparklingsGameControl.level.SparklingsNeeded;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error while loading level.\n\n" + ex.ToString());
            }
        }
        private void SaveLevel(Object sender, EventArgs e)
        {
            if (saveFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                string s = SparklingsGameControl.SaveLevel();
                using (var stream = saveFileDialog.OpenFile())
                {
                    using (var streamWriter = new StreamWriter(stream))
                    {
                        streamWriter.Write(s);
                    }
                }
            }
        }
        private void SwitchTestMode(Object sender, EventArgs e)
        {
            InPlayMode = !InPlayMode;
            buttonTestLevel.Text = InPlayMode ? "Stop Testing" : "Start Testing";
            TestModeChanged.Invoke();
        }
        private void ShowHelp()
        {
            MessageBox.Show(@"Commands

- Right click to place tiles.
- Press ""Start Testing"" to go into game mode. In this mode, changes
to the level are disabled, but you can interact with level elements.
Changes will be rolled-back when you click on ""Stop Testing"".
", "Help", MessageBoxButtons.OK);
        }
        private OpenFileDialog openFileDialog;
        private SaveFileDialog saveFileDialog;
        private NewLevelMessageBox newLevelMessageBox;
        public bool InPlayMode = false;
        public OnTestModeChanged TestModeChanged;
        public delegate void OnTestModeChanged();
    }
}
